package m3f.interact;

import m3f.data.MultimodalCachedLoader;
import m3f.data.MultimodalDataSet;
import m3f.factorization.OnlineJointFactorization;
import m3f.factorization.ParallelOnlineJointFactorization;
import m3f.io.DenseMatrixWriter;

public class Factorization {
	public static void factors(String[] args){
		// Data sources
		if (args.length < 15){
			System.out.println("Parameters: \n" +
					"\t1  Training matrix of visual features\n" +
					"\t2  Training matrix of textual \n" +
					"\t3  Test matrix of visual \n" +
					"\t4  Test matrix of textual \n" +
					"\t5  Number of latent factors \n" +
					"\t6  Visual regularizer (alpha) \n" +
					"\t7  Text regularizer (beta) \n" +
					"\t8  Latent regularizer (lambda) \n" +
					"\t9  Prediction regularizer (xi) \n" +
					"\t10 Initial step size (gamma0) \n" +
					"\t11 Text Weight (omega) \n" +
					"\t12 Minibatch size \n" +
					"\t13 Epochs \n" +
					"\t14 Training output file\n" +
					"\t15 Test output file\n" +
					"\t16 P output file\n" +
					"\t17 Q output file\n" +
					"\t18 Skip Error\n" +
					"\t19 Parallel run\n");
			System.exit(0);
		}
		String vFile = args[1];
		String tFile = args[2];
		String vtFile = args[3];
		String ttFile = args[4];
		// Model parameters
		int factors = Integer.valueOf(args[5]);
		double alpha = Double.valueOf(args[6]);
		double beta = Double.valueOf(args[7]);
		double lambda = Double.valueOf(args[8]);
		double xi = Double.valueOf(args[9]);
		double gamma0 = Double.valueOf(args[10]);
		double textWeight = Double.valueOf(args[11]);
		int minibatch = Integer.valueOf(args[12]);
		int epochs = Integer.valueOf(args[13]);
		String outputTraining = args[14];
		String outputTest = args[15];
		String outputP = args[16];
		String outputQ = args[17];
		boolean skipError = Boolean.parseBoolean(args[18]);
		boolean parallel = Boolean.parseBoolean(args[19]);
		// Run the algorithm
		long start = System.currentTimeMillis();
		MultimodalCachedLoader set = new MultimodalCachedLoader(vFile, tFile, true);
		OnlineJointFactorization factorization = null;
		if(parallel)
			factorization = new ParallelOnlineJointFactorization(set);
		else
			factorization = new OnlineJointFactorization(set);
		System.out.println("Loading training data: " + (System.currentTimeMillis()-start) + "ms");
		start = System.currentTimeMillis();
		factorization.run(factors, lambda, gamma0, alpha, beta, textWeight, epochs, minibatch, skipError);
		System.out.println("Factorization: " + (System.currentTimeMillis()-start) + "ms");
		factorization.writeLatentRepresentation(outputTraining);
		// Testing on unseen data
		start = System.currentTimeMillis();
		MultimodalDataSet test = new MultimodalDataSet(vtFile, ttFile, set.visualFeatures(), set.textFeatures(), true);
		DenseMatrixWriter.writeMatrix( factorization.projectVisualData(test, xi), outputTest, true);
		DenseMatrixWriter.writeMatrix( factorization.getP(), outputP, true);
		DenseMatrixWriter.writeMatrix( factorization.getQ(), outputQ, true);
		System.out.println("Processing test data: " + (System.currentTimeMillis()-start) + "ms");
	}
}
